//-----------------------------------------------------------------------------
//  Copyright (c) 2013 by HangZhou HenqgQiao Design Corporation. All rights reserved.
//
//  Project  : 
//  Module   : over sample the input data with 8-phases 311M clock
//  Parent   : 
//  Children : 
//
//  Description: 
//
//  Parameters:
//  Local Parameters:
//
//  Notes       : 
//
//  Multicycle and False Paths

module OBSI_ASIF(
   input                         OBSI_RESET,
   input                         OBSI_SYSCLK77,

 
   input                         OBSI_RXD,

   output reg                    ASIF_OUT_FP_0,
   output reg                    ASIF_OUT_FP_1,
   output reg                    ASIF_OUT_FP_2,
   output reg                    ASIF_OUT_FP_3,
   output reg                    ASIF_OUT_DEN_0,
   output reg                    ASIF_OUT_DEN_1,
   output reg                    ASIF_OUT_DEN_2,
   output reg                    ASIF_OUT_DEN_3,
   output reg[7:0]               ASIF_OUT_DATA_0,
   output reg[7:0]               ASIF_OUT_DATA_1,
   output reg[7:0]               ASIF_OUT_DATA_2,
   output reg[7:0]               ASIF_OUT_DATA_3
    );

reg[1:0]                         FAS_SMPL_CNT4;
reg[3:0]                         FAS_RXD_SMPL_REGS;

reg[47:0]                        FAS_FLAG_REG;
reg[1:0]                         FAS_FSM;
reg[11:0]                        FAS_CNT2430;

wire                             FAS_OUT_BIT_EN;
wire                             FAS_OUT_BIT_DATA;
wire[11:0]                       FAS_OUT_FMCNT2430;

wire[7:0]                        S2P_BYTE_DATA;
wire                             S2P_BYTE_EN;
wire[8:0]                        S2P_BYTE_CNT;

reg[6:0]                         S2P_SREG;




always @( posedge OBSI_SYSCLK77 or posedge OBSI_RESET ) begin
   if ( OBSI_RESET==1'b1 )
      FAS_SMPL_CNT4[1:0]                             <= 2'd0;
   else begin
      if ( FAS_FSM[1:0]==2'd0 && FAS_RXD_SMPL_REGS[3:0]==4'b0011 )
         FAS_SMPL_CNT4[1:0]                          <= 2'd1;
      else
         FAS_SMPL_CNT4[1:0]                          <= FAS_SMPL_CNT4[1:0] +2'd1;
   end
end

always @( posedge OBSI_SYSCLK77 or posedge OBSI_RESET ) begin
   if ( OBSI_RESET==1'b1 )
      FAS_RXD_SMPL_REGS[3:0]                         <= 4'd0;
   else
      FAS_RXD_SMPL_REGS[3:0]                         <= {FAS_RXD_SMPL_REGS[2:0], OBSI_RXD};
end




always @( posedge OBSI_SYSCLK77 or posedge OBSI_RESET ) begin
   if ( OBSI_RESET==1'b1 )
      FAS_FLAG_REG[47:0]                             <= 48'd0;
   else if ( FAS_SMPL_CNT4[1:0]== 2'd0 ) begin
      FAS_FLAG_REG[47:0]                             <= {FAS_FLAG_REG[46:0], FAS_RXD_SMPL_REGS[3]};
   end
end

always @( posedge OBSI_SYSCLK77 or posedge OBSI_RESET ) begin
   if ( OBSI_RESET==1'b1 ) begin
      FAS_FSM[1:0]                               <= 2'd0;
      FAS_CNT2430[11:0]                          <= 12'd0;
   end
   else begin
      case ( FAS_FSM[1:0] )
      2'b00: begin
         if ( FAS_RXD_SMPL_REGS[3:0]==4'b0011 )
            FAS_FSM[1:0]                         <= 2'd1;
         else
            FAS_FSM[1:0]                         <= 2'd0;
      end
      2'b01: begin
         if ( FAS_SMPL_CNT4[1:0]== 2'd0 ) begin
            if ( FAS_FLAG_REG[47:0]==48'hF6F6F6_282828 ) begin
               FAS_FSM[1:0]                         <= 2'd2;
               FAS_CNT2430[11:0]                    <= 12'd1;
            end
            else begin
               FAS_FSM[1:0]                         <= 2'd1;
               if ( FAS_CNT2430[11:0] ==12'd2429 )
                  FAS_CNT2430[11:0]                 <= 12'd0;
               else
                  FAS_CNT2430[11:0]                 <= FAS_CNT2430[11:0] +12'd1;
            end
         end
      end
      2'b10: begin      // normal state
         if ( FAS_SMPL_CNT4[1:0]== 2'd0 ) begin
            if ( FAS_CNT2430[11:0] ==12'd0 ) begin
               FAS_CNT2430[11:0]                    <= FAS_CNT2430[11:0] +12'd1;
               if ( FAS_FLAG_REG[47:0]!=48'hF6F6F6_282828 )
                  FAS_FSM[1:0]                      <= 2'd0;
               else
                  FAS_FSM[1:0]                      <= 2'd2;
            end
            else begin
                  FAS_FSM[1:0]                      <= 2'd2;
               if ( FAS_CNT2430[11:0] ==12'd2429 )
                  FAS_CNT2430[11:0]                 <= 12'd0;
               else
                  FAS_CNT2430[11:0]                 <= FAS_CNT2430[11:0] +12'd1;
            end
         end
      end
      default: begin
               FAS_FSM[1:0]                      <= 2'd0;
               FAS_CNT2430[11:0]                 <= 12'd0;
      end
      endcase
   end
end

  assign FAS_OUT_BIT_EN       = FAS_SMPL_CNT4[1:0]==2'd0;
  assign FAS_OUT_BIT_DATA     = FAS_FLAG_REG[47];
  assign FAS_OUT_FMCNT2430[11:0]    = FAS_CNT2430[11:0];




always @( posedge OBSI_SYSCLK77 or posedge OBSI_RESET ) begin
   if ( OBSI_RESET==1'b1 )
      S2P_SREG[6:0]                              <= 7'd0;
   else if ( FAS_OUT_BIT_EN==1'b1 )
      S2P_SREG[6:0]                              <= {S2P_SREG[5:0], FAS_OUT_BIT_DATA};
end
      

  assign S2P_BYTE_DATA[7:0]   = {S2P_SREG[6:0], FAS_OUT_BIT_DATA};
  assign S2P_BYTE_EN          = FAS_OUT_BIT_EN==1'b1 && FAS_OUT_FMCNT2430[2:0]==3'd7;
  assign S2P_BYTE_CNT[8:0]    = FAS_OUT_FMCNT2430[11:3];




//  ++++++++++++++++++       the otuput 4-channels data output     ++++++++++++++++++  //
always @( posedge OBSI_SYSCLK77 or posedge OBSI_RESET ) begin
   if ( OBSI_RESET==1'b1 ) begin
      ASIF_OUT_FP_0                              <= 1'b0;
      ASIF_OUT_FP_1                              <= 1'b0;
      ASIF_OUT_FP_2                              <= 1'b0;
      ASIF_OUT_FP_3                              <= 1'b0;
      ASIF_OUT_DEN_0                             <= 1'b0;
      ASIF_OUT_DEN_1                             <= 1'b0;
      ASIF_OUT_DEN_2                             <= 1'b0;
      ASIF_OUT_DEN_3                             <= 1'b0;
      ASIF_OUT_DATA_0[7:0]                       <= 8'd0;
      ASIF_OUT_DATA_1[7:0]                       <= 8'd0;
      ASIF_OUT_DATA_2[7:0]                       <= 8'd0;
      ASIF_OUT_DATA_3[7:0]                       <= 8'd0;
   end
   else begin
      ASIF_OUT_FP_0                              <= S2P_BYTE_EN==1'b1 && S2P_BYTE_CNT[8:0]==9'd6;
      ASIF_OUT_FP_1                              <= S2P_BYTE_EN==1'b1 && S2P_BYTE_CNT[8:0]==9'd38;
      ASIF_OUT_FP_2                              <= S2P_BYTE_EN==1'b1 && S2P_BYTE_CNT[8:0]==9'd70;
      ASIF_OUT_FP_3                              <= S2P_BYTE_EN==1'b1 && S2P_BYTE_CNT[8:0]==9'd102;
      ASIF_OUT_DEN_0                             <= S2P_BYTE_EN==1'b1 && ( S2P_BYTE_CNT[8:0]>=9'd6 && S2P_BYTE_CNT[8:0]<9'd38);
      ASIF_OUT_DEN_1                             <= S2P_BYTE_EN==1'b1 && ( S2P_BYTE_CNT[8:0]>=9'd38 && S2P_BYTE_CNT[8:0]<9'd70);
      ASIF_OUT_DEN_2                             <= S2P_BYTE_EN==1'b1 && ( S2P_BYTE_CNT[8:0]>=9'd70 && S2P_BYTE_CNT[8:0]<9'd102);
      ASIF_OUT_DEN_3                             <= S2P_BYTE_EN==1'b1 && ( S2P_BYTE_CNT[8:0]>=9'd102 && S2P_BYTE_CNT[8:0]<9'd134);
      ASIF_OUT_DATA_0[7:0]                       <= S2P_BYTE_DATA[7:0];
      ASIF_OUT_DATA_1[7:0]                       <= S2P_BYTE_DATA[7:0];
      ASIF_OUT_DATA_2[7:0]                       <= S2P_BYTE_DATA[7:0];
      ASIF_OUT_DATA_3[7:0]                       <= S2P_BYTE_DATA[7:0];
   end
end

endmodule


